home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / magazi~1 / 428 / capital.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-17  |  44.7 KB  |  1,672 lines

  1. /*    CAPITAL! The Ultimate Game of Finance.
  2.     ST Version by: Bryan P. Schappel
  3.     Written with: LASER C
  4. */
  5.  
  6. #include <gemdefs.h>
  7. #include <stdio.h>
  8. #include <osbind.h>
  9. #include <obdefs.h>
  10. #include "cap.h"
  11. #include "monospr.c"
  12. #include "colrspr.c"
  13. #include <linea.h>
  14.  
  15. #define LEFT 1
  16. #define RIGHT 2
  17. #define O_BINARY 8192
  18. #define NPROP 36
  19. #define FAST 1
  20. #define SLOW 2
  21. #define TRUE 1
  22. #define FALSE 0
  23. #define MY_DOUBLE 0
  24. #define NEWBUY 1
  25. #define NEWSEL 2
  26. #define NEWIMP 3
  27. #define DEBUG 1
  28. #define GOOD 1
  29. #define BAD 0
  30. #define UNOWNED -1
  31. #define RASTER_MODE 3
  32.  
  33. int work_in[11],            /* the usual GEM arrays */
  34.     work_out[57],
  35.     pxyarray[10],
  36.     contrl[12],
  37.     intin[128],
  38.     ptsin[128],
  39.     intout[128],
  40.     ptsout[128],
  41.     handle;                    /* workstation handle */
  42.  
  43. int bfee[] =            /* business fee */
  44.     {  0,  15,  14,   8,  25,  21,   0,  12,  20,  
  45.       22,  28,   0,   4,   6,  15,   7,   5,   0,  
  46.        5,   8,  14,  18,   0,   7,  19,   3,   0,  
  47.       16,  15,  21,  19,  14,   0,  31,  12,  10  };
  48.  
  49. int cost[] =            /* initial cost */
  50.     {  0,  23,  37,  25,  69,  65,   0,  41,  60,  
  51.       73,  84,   0,  12,  15,  38,  17,  13,   0,  
  52.       18,  27,  36,  37,   0,  22,  51,  11,   0,  
  53.       53,  48,  56,  61,  32,   0, 100,  47,  42  };
  54.  
  55. int reftab[] =         /* refresh table */
  56.     {128,   0,   0,   0,   2,   2,   4,   0,   0,  
  57.        2,   2, 128,   0,   0,   0,   2,   2, 128,  
  58.        0,   2,   2,   0,   4,   0,   0,   0, 128,  
  59.        2,   2,   0,   2,   2, 128,   0,   2,   2  };
  60.  
  61. int xref[] =            /* cross reference table */
  62.     {  0,   0,   0,   0,   5,   4,   0,   0,   0,  
  63.       10,   9,   0,   0,   0,   0,  16,  15,   0,  
  64.        0,  20,  19,   0,   0,   0,   0,   0,   0,  
  65.       28,  27,   0,  31,  30,   0,   0,  35,  34  };
  66.  
  67. char *prop_names[] =        /* property names */
  68.     { "Stock Market Dividends pay 12G",     "Wilt's Vegetables",
  69.       "Titanic Shipping",                      "Rex Auto Corporation",
  70.       "Schappel's Scalpels",                  "Stytch's Clinic",
  71.       "The Luck Square",                      "Crosstrax Railway",
  72.       "Black Gold Oil",                      "HAL Computers",
  73.       "Silicon Gulch",                      "Vacation time at the Hogg Hilton",
  74.       "Black Jack's Casino",                  "Death Valley Spa",
  75.       "Selmart Stores",                        "Adams Apple Orchard",
  76.       "Sour Grapes Vineyard",                  "IRS Audit: lose 12% of your cash",
  77.       "Drip Dry Cleaners",                      "Spud's Potato Farm",
  78.       "Bar-B-Q Ranch",                      "Jetstream Airlines",
  79.       "The Luck Square",                      "Ringading Telephone",
  80.       "IOU Penneys",                          "Thredbare Clothing",
  81.       "Vacation time at the Hogg Hilton",    "Kolbe's Cheese",
  82.       "Daisy's Dairy",                      "Steal Steelworks",
  83.       "Cross Eye Cable TV",                  "Olde Yorke Times",
  84.       "Capital Gains Tax",                      "Disastrous Insurance",
  85.       "Heavy Water Company",                  "Short Circuit Power & Light"  };
  86.  
  87. char *spaces = "                                ";
  88.  
  89. char *new_buttons[] =             /* button text */
  90.     { "DOUBLE",                    "NEXT",
  91.       "BACK",                    "SELECT"  };
  92.  
  93. char *player_names[] =             /* player name array */
  94.     { "Player 1",                    "Player 2",
  95.       "Player 3",                    "Player 4",
  96.       "None"  };
  97.  
  98. long *icon_addr[9],            /* icon addresses */
  99.      *dice[6];                /* dice icon addresses */
  100. int     *sprites[4];            /* sprite definition adresses */
  101.  
  102. char *options[] =             /* transaction option headings */
  103.     { " ",                    "Buy",
  104.       "Double",                "Sell",
  105.       "Improve",            "Forced Sale" };
  106.  
  107. spriteback spr1,spr2,spr3,spr4;
  108.      
  109. long usamap,backup;            /* pointer to screen */
  110. long scr_buf[8000];
  111.  
  112. lineaport *myport;            /* line a port variable */
  113.  
  114. int    who[NPROP],                /* property owners */
  115.     imp[NPROP],                /* property improvement levels */
  116.     rantab[NPROP],            /* random property value table */
  117.     refresh[NPROP],            /* refresh table */
  118.     gcost[NPROP],            /* cost of props in game */
  119.     gfee[NPROP],            /* prop fees in game */
  120.     cash[4],                /* players cash */
  121.     on_board[4],            /* players on board */
  122.     player,                    /* player that is up */
  123.     num_players,            /* number of players that start */
  124.     num_left,                /* number of players left */
  125.     rez,                    /* screen resolution */
  126.     offset = 1,                /* resolution conversion factor */
  127.     game_speed,                /* speed of game SLOW/FAST */
  128.     board_pos[4],            /* board positions of players */
  129.     nplanes = 4,            /* number of bit planes in screen */
  130.     desk_pal[16],            /* desktop palette */
  131.     dum;                    /* dummy */
  132.  
  133.     extern mouse_rts();
  134.  
  135.     unsigned char crash[] = { 0x06,0x1f,0x07,0x2f,0x09,0x10,
  136.                               0x0c,0x20,0x0d,0x00,0x81,0x12,
  137.                               0x02,0xf8,0xff,0x00 };
  138.  
  139.  
  140. /*********************************************************************
  141. *    get_tedinfo()
  142. *
  143. *    This function returns a pointer to a character array in a
  144. *    TEDINFO structure.  This is used so may of the other functions
  145. *    in this program can change the information in the numerous
  146. *    dialogs.
  147. **********************************************************************/
  148.  
  149. char *get_tedinfo (atree, object)
  150. OBJECT *atree;
  151. int       object;
  152. {
  153.     TEDINFO *ob_tedinfo;
  154.  
  155.     ob_tedinfo = (TEDINFO *) atree[object].ob_spec;
  156.     return ( ob_tedinfo->te_ptext );
  157. }
  158.  
  159.  
  160. /*********************************************************************
  161. *    main()
  162. *
  163. *    This is the MAIN routine.  Here we initialize the program and
  164. *    run the program from a loop until you decide to quit the game.
  165. **********************************************************************/
  166.     
  167. main()
  168. {
  169.     int current_prop,        /* current property */
  170.         dx,dy,dw,dh,
  171.         i,num,choice;
  172.     OBJECT *tree;
  173.     
  174.     appl_init();
  175.     graf_mouse(M_OFF,0L);
  176.     for (i = 0; i < 16; desk_pal[i++] = Setcolor(i,-1));
  177.     open_vwork();
  178.     v_clrwk(handle);
  179.     graf_mouse(M_ON,0L);
  180.     graf_mouse(ARROW,0L);
  181.     myport = a_init();
  182.     rez = Getrez();
  183.  
  184.     if ( ! rsrc_load("\CAP.RSC") )
  185.         form_alert(1,"[3][ |CAP.RSC File Missing!|Fatal Error.][ OOPS! ]");
  186.     else
  187.         if (rez == 1)
  188.             form_alert(1,"[3][ |CAPITAL! Only runs|in Low or High|Resolution][ OOPS! ]");
  189.         else {
  190.             usamap = (Malloc(32768L) & 0xffffff00) + 0x100;
  191.             backup = (Malloc(32768L) & 0xffffff00) + 0x100;
  192.             
  193.             if (rez == 2) {
  194.                 offset = 2;
  195.                 nplanes = 1;
  196.             }
  197.             load_map_screen();
  198.             do_intro();
  199.             
  200.             do {
  201.                 init_vars();
  202.                 get_names();
  203.                 player = 3;
  204.  
  205.                 do {
  206.                     current_prop = map_move();
  207.                     if (current_prop > 0) perform_trans(current_prop);
  208.                 } while (num_left > 1 && current_prop > 0);
  209.  
  210.                 if (num_left == 1) {
  211.                     rsrc_gaddr(0,WINDIAL,&tree);
  212.                     for (i = 0; i < 4; i++) if (on_board[i]) num = i;
  213.                     sprintf(get_tedinfo(tree,WIN_NAME),"%s Wins!",player_names[num]);
  214.                     draw_dialog(tree,&dx,&dy,&dw,&dh,TRUE);
  215.                     choice = form_do(tree,0);
  216.                     close_dialog(dx,dy,dw,dh,TRUE);
  217.                 }
  218.                 rsrc_gaddr(0,QUITGAME,&tree);
  219.                 draw_dialog(tree,&dx,&dy,&dw,&dh,TRUE);
  220.                 choice = form_do(tree,0);
  221.                 close_dialog(dx,dy,dw,dh,TRUE);
  222.             } while (choice != DESK_TOP);
  223.             
  224.             rsrc_free();
  225.             Mfree(usamap);
  226.             Mfree(backup);
  227.         }
  228.     graf_mouse(M_OFF,0L);
  229.     v_clrwk(handle);
  230.     graf_mouse(M_ON,0L);
  231.     graf_mouse(ARROW,0L);
  232.     v_clsvwk(handle);
  233.     Setpalette(desk_pal);
  234.     appl_exit();
  235. }
  236.  
  237.  
  238. /*********************************************************************
  239. *    map_move()
  240. *
  241. *    Here is where we move the player pieces around the MAP screen.
  242. *    The amount to move is determined by the Roll_dice() routine.
  243. *    After the dice have been thrown, the player piece is moved over
  244. *    each square.  Certain transactions are handled here, such as
  245. *    the Stock Market and Tax squares.
  246. **********************************************************************/
  247.  
  248. int map_move()
  249. {
  250.     int roll,i,j,flag,bp;
  251.  
  252.     flag = FALSE;
  253.     do {
  254.         do {
  255.             ++player;
  256.             if (player > 3) player = 0;
  257.             flag = on_board[player];
  258.         } while (flag == FALSE);
  259.         
  260.         draw_screen();
  261.         if (board_pos[player] == NPROP) board_pos[player] = 0;
  262.         roll = roll_dice();
  263.         bp = roll;
  264.         if (roll > 0) {
  265.             for (i = 0; i < roll; i++) {
  266.                 ++board_pos[player];
  267.                 if (board_pos[player] == NPROP) board_pos[player] = 0;
  268.                 sprite_move(player,board_pos[player]);
  269.                 print_prop(board_pos[player]);
  270.                 if (board_pos[player] == 0) {
  271.                     cash[player] += 12;
  272.                     form_dollar(TRUE);
  273.                     wait_jiffy(80);
  274.                 }
  275.                 wait_jiffy(20);
  276.             }
  277.             bp = board_pos[player];
  278.             if (bp == 17) {
  279.                 cash[player] -= cash[player] / 8;
  280.                 if (cash[player] <1) cash[player] = 1; /* tax break for the poor */
  281.                 form_dollar(TRUE);
  282.             }
  283.             if (bp == 17 || bp == 11 || bp == 26) wait_jiffy(80);
  284.         }
  285.     } while (bp == 17 || bp == 0 || bp == 11 || bp == 26);
  286.     return(bp);
  287. }
  288.  
  289.  
  290. /*********************************************************************
  291. *    open_vwork()
  292. *
  293. *    Open the Virtual Workstation.
  294. **********************************************************************/
  295.  
  296. open_vwork()
  297. {
  298.     int i;
  299.  
  300.     handle=graf_handle(&dum,&dum,&dum,&dum);
  301.     for (i=0; i<10; work_in[i++]=1);
  302.     work_in[10]=2;
  303.     v_opnvwk(work_in,&handle,work_out);
  304. }
  305.  
  306.  
  307. /*********************************************************************
  308. *    init_vars()
  309. *
  310. *    This routine initializes ALL of the game arrays and other
  311. *    variables.
  312. **********************************************************************/
  313.  
  314. init_vars()
  315. {
  316.     int i;                /* dummy index */
  317.  
  318.     for (i = 0; i < NPROP; i++) {
  319.         who[i] = UNOWNED;
  320.         imp[i] = 0;
  321.         refresh[i] = reftab[i];
  322.         gcost[i] = cost[i];
  323.         gfee[i] = bfee[i];
  324.     }
  325.  
  326.     for (i = 0; i < 4; i++) {
  327.         cash[i] = 375;
  328.         on_board[i] = FALSE;
  329.         board_pos[i] = NPROP;
  330.     }
  331.  
  332.     if (offset == 2) {
  333.         icon_addr[0] = sngl_ok;
  334.         icon_addr[1] = sngl_sold;
  335.         icon_addr[2] = dbl_ok;
  336.         icon_addr[3] = dbl_sold;
  337.         icon_addr[4] = luck_icon;
  338.         icon_addr[5] = hogg_icon;
  339.         icon_addr[6] = doll_icon;
  340.         icon_addr[7] = tax_icon;
  341.         icon_addr[8] = cgains;
  342.         sprites[0]     = mspr1;
  343.         sprites[1]     = mspr2;
  344.         sprites[2]   = mspr3;
  345.         sprites[3]   = mspr4;
  346.         dice[0]         = die1m;
  347.         dice[1]         = die2m;
  348.         dice[2]         = die3m;
  349.         dice[3]         = die4m;
  350.         dice[4]         = die5m;
  351.         dice[5]         = die6m;
  352.     }
  353.     else {
  354.         icon_addr[0] = csngok;
  355.         icon_addr[1] = csngsold;
  356.         icon_addr[2] = cdblok;
  357.         icon_addr[3] = cdblsold;
  358.         icon_addr[4] = cluck;
  359.         icon_addr[5] = chogg;
  360.         icon_addr[6] = cdoll;
  361.         icon_addr[7] = ctax;
  362.         icon_addr[8] = ccgain;
  363.         sprites[0]     = cspr1;
  364.         sprites[1]     = cspr2;
  365.         sprites[2]     = cspr3;
  366.         sprites[3]     = cspr4;
  367.         dice[0]         = cdie1;
  368.         dice[1]         = cdie2;
  369.         dice[2]         = cdie3;
  370.         dice[3]         = cdie4;
  371.         dice[4]         = cdie5;
  372.         dice[5]         = cdie6;
  373.     }
  374. }
  375.  
  376.  
  377. /*********************************************************************
  378. *    set_buttons()
  379. *
  380. *    This displays the OPTION buttons on the transaction dialog.  It
  381. *    updates the selectability of the buttons indicating what options
  382. *    are left to the player.
  383. **********************************************************************/
  384.  
  385. set_buttons(tree,buy,sell,improve)
  386. OBJECT  *tree;
  387. int        buy,sell,improve;
  388.  
  389. {
  390.     int x,y;            /* for dialog redraw */
  391.  
  392.     if (buy) tree[BUYBUTN].ob_state = NORMAL;
  393.     else tree[BUYBUTN].ob_state = DISABLED;
  394.  
  395.     if (sell) tree[SELBUTN].ob_state = NORMAL;
  396.     else tree[SELBUTN].ob_state = DISABLED;
  397.  
  398.     if (improve) tree[IMPBUTN].ob_state = NORMAL;
  399.     else tree[IMPBUTN].ob_state = DISABLED;
  400.  
  401.     objc_offset(tree,BUTNFLD,&x,&y);
  402.     objc_draw(tree,BUTNFLD,1,x,y,300,190);
  403.     draw_opt(tree);
  404.     form_dollar(FALSE);
  405. }
  406.  
  407.  
  408. /********************************************************************
  409. *    draw_opt()
  410. *
  411. *    This routine just draws the TRNOPTS field for the transaction
  412. *    processor.
  413. **********************************************************************/
  414.  
  415. draw_opt(tree)
  416. OBJECT *tree;
  417. {
  418.     int x,y;
  419.     
  420.     objc_offset(tree,TRNBOX,&x,&y);
  421.     objc_draw(tree,TRNBOX,1,x,y,96,16);
  422. }
  423.  
  424.  
  425. /*********************************************************************
  426. *    perform_trans()
  427. *
  428. *    This is the heart of the program - the transaction processor.
  429. *    This routine plays the BANKER for the game.  All properties are
  430. *    bought/sold/improved through this code.
  431. **********************************************************************/
  432.  
  433. perform_trans(cprop)
  434.     int cprop;
  435. {
  436.     OBJECT *tree_addr;        /* Object tree address */
  437.     char *oldptr,*optptr;
  438.     int disaster = FALSE,    /* disaster flag */
  439.         tprop,
  440.         tcost,
  441.         choice,                /* button choice */
  442.         dx,dy,dw,dh,        /* dialog box coords. */
  443.         x,y,                /* dialog portion coords. */
  444.         buy_flag = FALSE,    /* property buy flag */
  445.         sell_flag,            /* property sell flag */
  446.         imp_flag,            /* property improve flag */
  447.         opt_ok = FALSE,        /* option allow flag */
  448.         d_flag = FALSE;        /* dialog display flag */
  449.  
  450.     make_ran(disaster);
  451.     if (refresh[cprop] == 4) do_luck(&disaster);
  452.     else if (who[cprop] == UNOWNED && refresh[cprop] != 128) buy_flag = TRUE;
  453.  
  454.     sell_flag = haveany();
  455.     imp_flag  = sell_flag;
  456.     opt_ok = !sell_flag;
  457.     
  458.     if ((who[cprop] != UNOWNED) && (who[cprop] != player)) pay_fee(&disaster,cprop);
  459.     if (cprop == 32) capital_gains(&disaster);
  460.  
  461.     if (buy_flag || sell_flag || imp_flag || disaster) {    
  462.         rsrc_gaddr(0,TRANSACT,&tree_addr);
  463.         optptr = get_tedinfo(tree_addr,TRNOPTS);
  464.         sprintf(optptr,"%s",options[0]);
  465.         insert_prop(tree_addr,cprop);
  466.         sprintf(get_tedinfo(tree_addr,TRANPLR),"For: %s",player_names[player]);
  467.  
  468.         if ((disaster == TRUE) && (game_speed == SLOW)) {
  469.             draw_dialog(tree_addr,&dx,&dy,&dw,&dh,FALSE);
  470.             set_buttons(tree_addr,buy_flag,sell_flag,imp_flag);
  471.             force_sale(&disaster,tree_addr);
  472.             d_flag = TRUE;
  473.         }
  474.  
  475.         if (!disaster) {
  476.         if (!d_flag) {
  477.             draw_dialog(tree_addr,&dx,&dy,&dw,&dh,FALSE);
  478.             set_buttons(tree_addr,buy_flag,sell_flag,imp_flag);
  479.             d_flag = TRUE;
  480.         }
  481.             do {
  482.                 choice = form_do(tree_addr,0);
  483.                 if (choice == BUYBUTN && buy_flag == TRUE) {
  484.                     sprintf(optptr,"%s",options[1]);
  485.                     draw_opt(tree_addr);
  486.                     buy_it(tree_addr,cprop);
  487.                     if (who[cprop] != UNOWNED && xref[cprop] != 0) {
  488.                         tprop = cprop;
  489.                         cprop = xref[tprop];
  490.                         tcost = gcost[cprop];
  491.                         gcost[cprop] *= 2;
  492.                         oldptr = (char *)tree_addr[BUYBUTN].ob_spec;
  493.                         (char *)tree_addr[BUYBUTN].ob_spec = new_buttons[MY_DOUBLE];
  494.                         sprintf(optptr,"%s",options[2]);
  495.                         set_buttons(tree_addr,TRUE,FALSE,FALSE);
  496.                         show_prop(tree_addr,cprop);
  497.                         do {
  498.                             choice = form_do(tree_addr,0);
  499.                             if (choice == BUYBUTN) {
  500.                                 buy_it(tree_addr,cprop);
  501.                                 choice = TEXIT;
  502.                             }
  503.                         } while (choice != TEXIT);
  504.                         (char *)tree_addr[BUYBUTN].ob_spec = oldptr;
  505.                         gcost[cprop] = tcost;
  506.                         cprop = tprop;
  507.                         show_prop(tree_addr,cprop);
  508.                     }
  509.                     buy_flag = FALSE;
  510.                     if (opt_ok) {
  511.                         imp_flag = haveany();
  512.                         sell_flag = imp_flag;
  513.                     }
  514.                     choice = BUYBUTN;
  515.                 }
  516.                 if (choice == IMPBUTN && imp_flag == TRUE) {
  517.                     sprintf(optptr,"%s",options[4]);
  518.                     draw_opt(tree_addr);
  519.                     imp_it(tree_addr);
  520.                     imp_flag = FALSE;
  521.                 }
  522.                 if (choice == SELBUTN && sell_flag == TRUE) {
  523.                     sprintf(optptr,"%s",options[3]);
  524.                     set_buttons(tree_addr,buy_flag,sell_flag,imp_flag);
  525.                     sell_it(tree_addr,disaster);
  526.                     sell_flag = FALSE;
  527.                 }
  528.                 if ((buy_flag == FALSE) && (sell_flag == FALSE) && (imp_flag == FALSE)) choice = TEXIT;
  529.                 sprintf(optptr,"%s",options[0]);
  530.                 set_buttons(tree_addr,buy_flag,sell_flag,imp_flag);
  531.             } while (choice != TEXIT);
  532.         close_dialog(dx,dy,dw,dh,FALSE);
  533.         }
  534.         else {    /* disaster is TRUE */
  535.             if (d_flag) close_dialog(dx,dy,dw,dh,FALSE);
  536.             cash[player] = 0;
  537.             form_dollar(FALSE);
  538.             rsrc_gaddr(0,DEADIAL,&tree_addr);
  539.             sprintf(get_tedinfo(tree_addr,BRNAME),"%s",player_names[player]);
  540.             draw_dialog(tree_addr,&dx,&dy,&dw,&dh,TRUE);
  541.             form_do(tree_addr,0);
  542.             close_dialog(dx,dy,dw,dh,TRUE);
  543.  
  544.             on_board[player] = FALSE;
  545.             --num_left;
  546.             cprop = 0;
  547.             for (cprop = 0; cprop < NPROP; cprop++)
  548.                 if (who[cprop] == player) {
  549.                     who[cprop] = UNOWNED;
  550.                     --refresh[cprop];
  551.                     if (gcost[cprop] > 1) gcost[cprop] /= 2;
  552.                 }
  553.         }
  554.     }
  555. }
  556.  
  557.  
  558. /*********************************************************************
  559. *    buy_it()
  560. *
  561. *    This routine is responsible for selling a property to a player.
  562. *    If the player has enough cash, the sale is allowed otherwise
  563. *    the sale is aborted.
  564. **********************************************************************/
  565.  
  566. buy_it(tree,property)
  567. OBJECT *tree;
  568. int property;
  569. {
  570.     if (cash[player] > gcost[property]) {
  571.         cash[player] -= gcost[property];
  572.         ++refresh[property];
  573.         who[property] = player;
  574.         show_prop(tree,property);
  575.         trans_ok();
  576.     }
  577.     else no_cash();
  578. }
  579.  
  580.  
  581. /*********************************************************************
  582. *    imp_it()
  583. *
  584. *    This routine allows a player to improve one of his properties.
  585. *    If the player has enough cash, the player selects the property
  586. *    and the improvement is made.
  587. **********************************************************************/
  588.  
  589. imp_it(tree)
  590. OBJECT *tree;
  591. {
  592.     int    property;
  593.  
  594.     if (haveany() == TRUE) {
  595.         if (cash[player] < 11) no_cash();
  596.         else {
  597.             property = pick_prop(tree,FALSE);
  598.             if (property > UNOWNED) if (imp[property] < 3) {
  599.                 ++imp[property];
  600.                 gfee[property] *= 2;
  601.                 gcost[property] += 5;
  602.                 cash[player] -= 10;
  603.                 show_prop(tree,property);
  604.                 trans_ok();
  605.             }
  606.         }
  607.     }
  608. }
  609.  
  610.  
  611. /*********************************************************************
  612. *    sell_it()
  613. *
  614. *    This routine lets players sell properties.  The player makes the
  615. *    choice of which property goes and it is put up for sale again.
  616. **********************************************************************/
  617.  
  618. sell_it(tree,disaster)
  619. OBJECT *tree;
  620. int       disaster;
  621. {
  622.     int property;        /* property to sell */
  623.  
  624.     if (haveany() == TRUE) {
  625.         property = pick_prop(tree,disaster);
  626.         if (property != UNOWNED) {
  627.             who[property] = UNOWNED;
  628.             cash[player] += rantab[property];
  629.             --refresh[property];
  630.             show_prop(tree,property);
  631.             trans_ok();
  632.         }
  633.     }
  634. }
  635.  
  636.  
  637. /*********************************************************************
  638. *    haveany()
  639. *
  640. *    This function scans the property owner list for any properties
  641. *    that the current player may own.  If a match is found then the
  642. *    player owns some properties and we can return a TRUE otherwise
  643. *    we return a FALSE.
  644. **********************************************************************/
  645.  
  646. int haveany()
  647. {
  648.     int i, flag = FALSE;    /* loop variable & flag */
  649.  
  650.     for (i = 0; i < NPROP; i++) if (who[i] == player) flag = TRUE;
  651.     return(flag);
  652. }
  653.  
  654.  
  655. /*********************************************************************
  656. *    pick_prop()
  657. *
  658. *    This function allows the current player to scan through their
  659. *    properties and select one to sell or improve.  This function
  660. *    makes some changes to the BUTNFLD buttons in the TRANSACT
  661. *    dialog.  If the disaster flag is set the player MUST choose
  662. *    a property, he can't press the EXIT button.
  663. **********************************************************************/
  664.  
  665. pick_prop(tree,disaster)
  666. OBJECT *tree;
  667. int disaster;
  668.  
  669. {
  670.     int    property,            /* current property number */
  671.         choice,                /* button choice */
  672.         select_flg = FALSE,    /* select flag */
  673.         props[NPROP],        /* owned property array */
  674.         num_owned = 0,        /* number of props owned */
  675.         num = 0,            /* number of current property */
  676.         i,                    /* junk loop variable */
  677.         add;                /* property addition factor */
  678.     char *oldbuy,*oldsel,*oldimp; /* hold variables */
  679.  
  680.     if (haveany()) {
  681.         for (i = 0; i < NPROP; i++)
  682.             if (who[i] == player) {
  683.                 props[num_owned] = i;
  684.                 ++num_owned;
  685.             }
  686.  
  687.         oldbuy = (char *)tree[BUYBUTN].ob_spec;
  688.         (char *)tree[BUYBUTN].ob_spec = new_buttons[NEWBUY];
  689.         oldsel = (char *)tree[SELBUTN].ob_spec;
  690.         (char *)tree[SELBUTN].ob_spec = new_buttons[NEWSEL];
  691.         oldimp = (char *)tree[IMPBUTN].ob_spec;
  692.         (char *)tree[IMPBUTN].ob_spec = new_buttons[NEWIMP];
  693.  
  694.         if (disaster) {
  695.             tree[TEXIT].ob_state = DISABLED;
  696.             sprintf(get_tedinfo(tree,TRNOPTS),"%s",options[5]);
  697.             set_buttons(tree,TRUE,TRUE,TRUE);
  698.         }
  699.         else {
  700.             tree[TEXIT].ob_state = NORMAL;
  701.             set_buttons(tree,TRUE,TRUE,TRUE);
  702.         }
  703.  
  704.         do {
  705.             property = props[num];
  706.             add = 1;
  707.             select_flg = FALSE;
  708.             show_prop(tree,property);
  709.             add = 10;
  710.             do {
  711.                 choice = form_do(tree,0);
  712.                 if (choice == BUYBUTN) add = 1;
  713.                 if (choice == SELBUTN) add = -1;
  714.                 if (choice == IMPBUTN) {
  715.                     select_flg = TRUE;
  716.                     add = 0;
  717.                 }
  718.                 if (choice == TEXIT && disaster == FALSE) {
  719.                     property = UNOWNED;
  720.                     add = 0;
  721.                     select_flg = TRUE;
  722.                 }
  723.             } while (add == 10);
  724.             num += add;
  725.             if (select_flg == FALSE) {
  726.                 if (num < 0) num = num_owned - 1;
  727.                 if (num == num_owned) num = 0;
  728.             }
  729.         } while (select_flg == FALSE);
  730.     (char *)tree[BUYBUTN].ob_spec = oldbuy;
  731.     (char *)tree[SELBUTN].ob_spec = oldsel;
  732.     (char *)tree[IMPBUTN].ob_spec = oldimp;
  733.     tree[TEXIT].ob_state  = NORMAL;
  734.     set_buttons(tree,TRUE,TRUE,TRUE);
  735.     }
  736.     return(property);
  737. }
  738.  
  739.  
  740. /*********************************************************************
  741. *    trans_ok()
  742. *
  743. *    This routine displays a small alert box informing the player that
  744. *    the last selected transaction has been processed successfully.
  745. **********************************************************************/
  746.  
  747. trans_ok()
  748. {
  749.     form_dollar(FALSE);
  750.     form_alert(1,"[0][ |Transaction Processed  ][ OK ]");
  751. }
  752.  
  753.  
  754. /*********************************************************************
  755. *    no_cash()
  756. *
  757. *    This routine just displays a small alert box informing the player
  758. *    that they don't have enough cash on hand for the purchase.
  759. **********************************************************************/
  760.  
  761. no_cash()
  762. {
  763.     form_dollar(FALSE);
  764.     form_alert(1,"[0][ |Insufficient Funds  ][ OK ]");
  765. }
  766.  
  767.  
  768. /*********************************************************************
  769. *    get_fee()
  770. *
  771. *    This function returns the fee for the property that the player
  772. *    has just landed on.  If the property is part of a double and both
  773. *    halves of the double are owned by the same player, the fee is the
  774. *    sum of the two properties.
  775. **********************************************************************/
  776.  
  777. int get_fee(prop)
  778. int prop;
  779. {
  780.     int the_fee;
  781.  
  782.     the_fee = gfee[prop];
  783.     if (xref[prop] != 0 && who[prop] != UNOWNED) 
  784.         if (who[prop] == who[xref[prop]]) the_fee += gfee[xref[prop]];
  785.     return(the_fee);
  786. }
  787.  
  788.  
  789. /*********************************************************************
  790. *    insert_prop()
  791. *
  792. *    This routine puts the property information into the TRANSACT
  793. *    dialog's TEDINFO structures.
  794. **********************************************************************/
  795.  
  796. insert_prop(tree,prop)
  797. OBJECT *tree;
  798. int prop;
  799. {
  800.     char *string;            /* temp string pointer */
  801.     int  p_owner;            /* owner number */
  802.  
  803.     sprintf(get_tedinfo(tree,PROPERTY), "Prop: %s", prop_names[prop]);
  804.     sprintf(get_tedinfo(tree,RESALE), "Resale: %dG", rantab[prop]);
  805.     sprintf(get_tedinfo(tree,PRICE), "Price: %dG", gcost[prop]);
  806.     sprintf(get_tedinfo(tree,LEVEL), "Level: %d", imp[prop]);
  807.  
  808.     string = get_tedinfo(tree,DOUBLE);
  809.     if (xref[prop] == 0) sprintf(string, "Double: No");
  810.     else sprintf(string, "Double: Yes");
  811.  
  812.     sprintf(get_tedinfo(tree,FEE), "Fee: %dG", get_fee(prop));
  813.  
  814.     p_owner = who[prop];
  815.     if (p_owner == UNOWNED) p_owner = 4;
  816.     string = get_tedinfo(tree,OWNER);
  817.     sprintf(string, "Owner: %s",player_names[p_owner]);
  818. }
  819.  
  820.  
  821. /*********************************************************************
  822. *    show_prop()
  823. *
  824. *    This routine shows the information for the current property.
  825. *    It just redraws a section of the TRANSACT dialog to accomplish
  826. *    this little feat.
  827. **********************************************************************/
  828.  
  829. show_prop(tree,prop)
  830. OBJECT *tree;
  831. int prop;                        /* property number */
  832.  
  833. {
  834.     int    prop_x,prop_y;            /* property area x, y */
  835.  
  836.     insert_prop(tree,prop);        /* put in property info */
  837.     objc_offset(tree, PROPFLD, &prop_x, &prop_y);
  838.     objc_draw(tree, PROPFLD, 2, prop_x, prop_y, 320, 80);
  839. }
  840.  
  841.  
  842. /*********************************************************************
  843. *    get_names()
  844. *
  845. *    This routine is responsible for getting the parameters for the
  846. *    upcoming game.  Such as: # of players, speed of game and the
  847. *    names of the players.
  848. **********************************************************************/
  849.  
  850. get_names()
  851. {
  852.     OBJECT *tree;
  853.     int    x,y;                /* x, y of input box */
  854.     int    dx,dy,dw,dh;        /* dialog x,y,w,h */
  855.     int       choice;            /* button choice */
  856.     int       i;                /* loop variable */
  857.  
  858.     rsrc_gaddr(0,NAMEDIAL,&tree);
  859.  
  860.     tree[FASTBUTN].ob_state = SELECTED;
  861.     tree[SLOWBUTN].ob_state = NORMAL;
  862.     tree[PBUT2].ob_state    = SELECTED | SHADOWED;
  863.     tree[PBUT3].ob_state    = SHADOWED;
  864.     tree[PBUT4].ob_state    = SHADOWED;
  865.  
  866.     num_players = 2;
  867.     game_speed = FAST;
  868.  
  869.     draw_dialog(tree,&dx,&dy,&dw,&dh,TRUE);
  870.     draw_name_area(tree);
  871.     draw_em(tree,SELECTED,NORMAL);
  872.     graf_mouse(ARROW,0L);
  873.  
  874.     do {
  875.         choice = form_do(tree,PEDIT1);
  876.         if (choice == PBUT2) {
  877.             num_players = 2;
  878.             draw_name_area(tree);
  879.         }
  880.         if (choice == PBUT3) {
  881.             num_players = 3;
  882.             draw_name_area(tree);
  883.         }
  884.         if (choice == PBUT4) {
  885.             num_players = 4;
  886.             draw_name_area(tree);
  887.         }
  888.         if (choice == FASTBUTN) {
  889.             game_speed = FAST;
  890.             draw_em(tree,SELECTED,NORMAL);
  891.         }
  892.         if (choice == SLOWBUTN) {
  893.             game_speed = SLOW;
  894.             draw_em(tree,NORMAL,SELECTED);
  895.         }
  896.     }
  897.     while (choice != DONEBUTN);
  898.     close_dialog(dx,dy,dw,dh,TRUE);
  899. }
  900.  
  901.  
  902. /*********************************************************************
  903. *    draw_name_area()
  904. *
  905. *    This routine draws the PLAYER NAME area of the get_names()
  906. *    screen.
  907. **********************************************************************/
  908.  
  909. draw_name_area(tree)
  910. OBJECT *tree;
  911. {
  912.     int dx,dy,x;
  913.     for (x = PEDIT1; x < PEDIT4 + 1; x++) {
  914.         tree[x].ob_state = NORMAL;
  915.         tree[x].ob_flags = HIDETREE;
  916.         on_board[x - PEDIT1] = FALSE;
  917.     }
  918.  
  919.     tree[DONEBUTN].ob_state = NORMAL;
  920.     objc_offset(tree,DONEBUTN,&dx,&dy);
  921.     objc_draw(tree,DONEBUTN,1,dx,dy,75,24);
  922.  
  923.     for (x = 0; x < num_players; x++) {
  924.         tree[PEDIT1 + x].ob_flags = EDITABLE;
  925.         on_board[x] = TRUE;
  926.     }
  927.  
  928.     objc_offset(tree,PLR_NAME,&dx,&dy);
  929.     objc_draw(tree,PLR_NAME,2,dx,dy,170,200);
  930.     num_left = num_players;    
  931.     for (x = 0; x < 4; x++) player_names[x] = get_tedinfo(tree,PEDIT1+x);
  932. }    
  933.     
  934.  
  935. /*********************************************************************
  936. *    draw_em()
  937. *
  938. *    This routine just draws the game speed buttons on the NAMEDIAL
  939. *    screen.
  940. **********************************************************************/
  941.  
  942. draw_em(tree,flag1,flag2)
  943. OBJECT *tree;
  944. int flag1,flag2;
  945. {
  946.     int x,y;
  947.     
  948.     tree[FASTBUTN].ob_state = flag1;
  949.     tree[SLOWBUTN].ob_state = flag2;
  950.     objc_offset(tree,FASTBUTN,&x,&y);
  951.     objc_draw(tree,FASTBUTN,2,x,y,32,16);
  952.     objc_offset(tree,SLOWBUTN,&x,&y);
  953.     objc_draw(tree,SLOWBUTN,2,x,y,32,16);
  954. }
  955.  
  956.  
  957. /*********************************************************************
  958. *    do_luck()
  959. *
  960. *    This is the LUCK routine.  This routine is called when a player
  961. *    lands on a luck square.  First we determine whether the player
  962. *    has good luck or bad, then we pick one of three 'goodies' and
  963. *    give it to the player.  The LUCKDIAL dialog is used to tell
  964. *    the player what they won/lost.
  965. **********************************************************************/
  966.  
  967. do_luck(disaster)
  968. int *disaster;
  969. {
  970.     int luck,
  971.         luck_num;
  972.     char *string,*string2;
  973.     OBJECT *tree;
  974.     int dx,dy,dw,dh,property,choice;
  975.  
  976.     rsrc_gaddr(0,LUCKDIAL,&tree);
  977.     luck = Random() & 0x01;
  978.     string = get_tedinfo(tree,LUCK1);
  979.     if (luck == GOOD) sprintf(string,"Your luck was: Good");
  980.     else sprintf(string,"Your luck was: Bad");
  981.  
  982.     sprintf(get_tedinfo(tree,LUCKNAME),"%s",player_names[player]);
  983.     string = get_tedinfo(tree,LUCK2);
  984.     string2 = get_tedinfo(tree,LUCK3);
  985.     
  986.     luck_num = rnd(3);
  987.     
  988.     if ((luck == BAD) && (haveany() == FALSE)) luck_num = 0;
  989.     if ((luck == GOOD) && (haveany() == FALSE) && (luck_num == 2)) luck_num = 0;
  990.     
  991.     if (luck == GOOD)
  992.         switch (luck_num) {
  993.             case 0:
  994.                  cash[player] += 10;
  995.                  sprintf(string,"You win:");
  996.                  sprintf(string2,"10G");
  997.                  break;
  998.             case 1:
  999.                  cash[player] += 15;
  1000.                  sprintf(string,"You win:");
  1001.                  sprintf(string2,"15G");
  1002.                  break;
  1003.             case 2:
  1004.                  property = get_random_prop();
  1005.                  if (imp[property] == 3) {
  1006.                      cash[player] += 10;
  1007.                      sprintf(string,"You win:");
  1008.                      sprintf(string2,"10G");
  1009.                  }
  1010.                  else {
  1011.                      ++imp[property];
  1012.                      gfee[property] *= 2;
  1013.                      gcost[property] += 5;
  1014.                      sprintf(string,"You win improvement on:");
  1015.                      sprintf(string2,"%s",prop_names[property]);
  1016.                  }
  1017.                  break;
  1018.         }
  1019.     else
  1020.         switch (luck_num) {
  1021.             case 0:
  1022.                  cash[player] -= 10;
  1023.                  sprintf(string,"You lose:");
  1024.                  sprintf(string2,"10G");
  1025.                  break;
  1026.             case 1:
  1027.                  property = get_random_prop();
  1028.                  if (gfee[property] < 1) {
  1029.                      cash[player] -= 10;
  1030.                      sprintf(string,"You lose:");
  1031.                      sprintf(string2,"10G");
  1032.                  }
  1033.                  else {
  1034.                      gfee[property] /= 2;
  1035.                      sprintf(string,"You lose 1/2 fee on:");
  1036.                      sprintf(string2,"%s",prop_names[property]);
  1037.                  }
  1038.             case 2:
  1039.                  property = get_random_prop();
  1040.                  if (gcost[property] < 2) {
  1041.                      cash[player] -= 10;
  1042.                      sprintf(string,"You lose:");
  1043.                      sprintf(string2,"10G");
  1044.                  }
  1045.                  else {
  1046.                      gcost[property] /= 2;
  1047.                      sprintf(string,"You lose 1/2 value on:");
  1048.                      sprintf(string2,"%s",prop_names[property]);
  1049.                  }
  1050.         }
  1051.     if (cash[player] < 1) *disaster = TRUE;
  1052.     form_dollar(FALSE);
  1053.     draw_dialog(tree,&dx,&dy,&dw,&dh,TRUE);
  1054.     form_do(tree,0);
  1055.     close_dialog(dx,dy,dw,dh,TRUE);
  1056. }
  1057.  
  1058.  
  1059. /*********************************************************************
  1060. *    make_ran()
  1061. *
  1062. *    This routine creates the RANDOM value property table.  This
  1063. *    table depends on whether or not the DISASTER flag is set.  The
  1064. *    values range from 1/2 to full price (if DISASTER is FALSE) or
  1065. *    just 1/2 price (if DISASTER is TRUE).
  1066. **********************************************************************/
  1067.  
  1068. make_ran(disaster)
  1069. int disaster;
  1070. {
  1071.     int my_ran,
  1072.         property = 0;
  1073.  
  1074.     do {
  1075.         rantab[property] = gcost[property];
  1076.         if ((who[property] == player) && (gcost[property] > 1)) {
  1077.             rantab[property] /= 2;
  1078.             if ( !disaster ) rantab[property] += rnd(rantab[property]);
  1079.         }
  1080.         ++property;
  1081.     } while(property < NPROP);
  1082. }
  1083.  
  1084.  
  1085. /*********************************************************************
  1086. *    rnd()
  1087. *
  1088. *    This function returns a random number between 0 & n-1.
  1089. **********************************************************************/
  1090.  
  1091. int rnd( n )
  1092. int n;
  1093. {
  1094.     int r;
  1095.     
  1096.     r = (int)Random();
  1097.     return(abs(r) % n);
  1098. }
  1099.  
  1100.  
  1101. /*********************************************************************
  1102. *    get_random_prop()
  1103. *
  1104. *    This routine gets a random property number that is owned by
  1105. *    the current player for the luck routine.
  1106. **********************************************************************/
  1107.  
  1108. int get_random_prop()
  1109. {
  1110.     int prop_array[NPROP],
  1111.         index = 0,
  1112.         current = 0;
  1113.     
  1114.     do {
  1115.         if (who[current] == player) {
  1116.             prop_array[index] = current;
  1117.             ++index;
  1118.         }
  1119.         ++current;
  1120.     } while (current < NPROP);
  1121.     
  1122.     current = rnd(index);
  1123.         
  1124.     return(prop_array[current]);
  1125. }
  1126.  
  1127.  
  1128. /*********************************************************************
  1129. *    pay_fee()
  1130. *
  1131. *    This routine exacts the fee from the hide of the current player.
  1132. *    If the player does not have the money, the disaster flag is    set.
  1133. **********************************************************************/
  1134.  
  1135. pay_fee(disaster,property)
  1136. int *disaster,property;
  1137. {
  1138.     int dx,dy,dw,dh,choice,the_fee;
  1139.     OBJECT *tree;
  1140.     char *string;
  1141.  
  1142.     the_fee = get_fee(property);
  1143.     cash[player] -= the_fee;
  1144.     if (cash[player] < 1) *disaster = TRUE;
  1145.     rsrc_gaddr(0,FEE_DIAL,&tree);
  1146.  
  1147.     sprintf(get_tedinfo(tree,FEE_1),player_names[player]);
  1148.     sprintf(get_tedinfo(tree,FEE_3),player_names[who[property]]);
  1149.     sprintf(get_tedinfo(tree,FEE_2),"pays %dG to",the_fee);
  1150.  
  1151.     cash[who[property]] += the_fee;
  1152.     draw_dialog(tree,&dx,&dy,&dw,&dh,TRUE);
  1153.     form_do(tree,0);
  1154.     close_dialog(dx,dy,dw,dh,TRUE);
  1155. }
  1156.  
  1157.  
  1158. /*********************************************************************
  1159. *    capital_gains()
  1160. *
  1161. *    This routine is for the CAPITAL GAINS TAX square.  If the player
  1162. *    lands here, they lose 45G!
  1163. **********************************************************************/
  1164.  
  1165. capital_gains(disaster)
  1166. int *disaster;
  1167. {
  1168.     int choice,dx,dy,dw,dh;
  1169.     OBJECT *tree;
  1170.     
  1171.     rsrc_gaddr(0,CAPGAINS,&tree);
  1172.     sprintf(get_tedinfo(tree,CG_NAME),"%s",player_names[player]);
  1173.     draw_dialog(tree,&dx,&dy,&dw,&dh,TRUE);
  1174.     form_do(tree,0);
  1175.     close_dialog(dx,dy,dw,dh,TRUE);
  1176.     cash[player] -= 45;
  1177.     form_dollar(FALSE);
  1178.     if (cash[player] < 1) *disaster = TRUE;
  1179. }
  1180.  
  1181.  
  1182. /*********************************************************************
  1183. *    force_sale()
  1184. *
  1185. *    This routine forces a player to sell off his/her properties in
  1186. *    case of a disaster.  This is done so that other players get their
  1187. *    fee.  If the player sells enough properties to pay the debt
  1188. *    the disaster flag is set to FALSE, otherwise the player is
  1189. *    BROKE and is out of the game.
  1190. **********************************************************************/
  1191.  
  1192. force_sale(disaster,tree)
  1193. int *disaster;
  1194. OBJECT *tree;
  1195. {
  1196.     int i,
  1197.         property,
  1198.         value = 0;
  1199.     
  1200.     if ((haveany() == TRUE) && (game_speed == SLOW)) {
  1201.         for (i = 0; i < NPROP; i++) if (who[i] == player) value += rantab[i];
  1202.         if (cash[player] + value > 0) {
  1203.             make_ran(TRUE);
  1204.             do {
  1205.             property = pick_prop(tree,TRUE);
  1206.             who[property] = UNOWNED;
  1207.             cash[player] += rantab[property];
  1208.             form_dollar(FALSE);
  1209.             --refresh[property];
  1210.             } while (cash[player] < 1);
  1211.             *disaster = FALSE;
  1212.             make_ran(FALSE);
  1213.         }
  1214.     }
  1215. }
  1216.  
  1217.  
  1218. /*********************************************************************
  1219. *    draw_icon()
  1220. *
  1221. *    This routine is used to draw the dice and properties on the
  1222. *    screen.  The routine was taken from the Moon Lord source.
  1223. **********************************************************************/
  1224.  
  1225. draw_icon( data, mode, dx, dy, width, height)
  1226. long data;
  1227. int mode,dx,dy,width,height;
  1228. {
  1229.     MFDB s_m,scr_m;
  1230.     int pxy[8];
  1231.  
  1232.     s_m.fd_addr = data;
  1233.     s_m.fd_w    = width;
  1234.     s_m.fd_h    = height;
  1235.     s_m.fd_wdwidth = width / 16;
  1236.     s_m.fd_stand= 0;
  1237.     s_m.fd_nplanes = nplanes;
  1238.     scr_m.fd_addr = 0;
  1239.     pxy[0] = 0;
  1240.     pxy[1] = 0;
  1241.     pxy[2] = width;
  1242.     pxy[3] = height;
  1243.     pxy[4] = dx;
  1244.     pxy[5] = dy;
  1245.     pxy[6] = dx + width;
  1246.     pxy[7] = dy + height;
  1247.     vro_cpyfm(handle,mode,pxy,&s_m,&scr_m);
  1248. }
  1249.  
  1250.  
  1251. /*********************************************************************
  1252. *    draw_screen()
  1253. *
  1254. *    This function draws all the icons on the screen for the MAP
  1255. *    handler.  The addresses of the icons to draw are stored in the
  1256. *    icon_addr array.
  1257. **********************************************************************/
  1258.  
  1259. draw_screen()
  1260. {
  1261.     int index,icon_num;
  1262.     long phys_scr,log_scr;
  1263.  
  1264.     graf_mouse(M_OFF,0L);
  1265.     phys_scr = Physbase();
  1266.     log_scr  = Logbase();
  1267.     scr_copy(phys_scr,backup);
  1268.     Setscreen(log_scr,backup,-1);
  1269.     Vsync();
  1270.     scr_copy(usamap,phys_scr);
  1271.     for (index = 0; index < NPROP; index++) {
  1272.         icon_num = refresh[index];
  1273.         if (index ==  0)                icon_num = 6; /* stock market */
  1274.         if (index == 32)                 icon_num = 8; /* capital gains */
  1275.         if (index == 11 || index == 26) icon_num = 5; /* hogg hilton */
  1276.         if (index ==  6 || index == 22) icon_num = 4; /* luck */
  1277.         if (index == 17)                icon_num = 7; /* tax man */
  1278.         if (offset == 2) draw_icon(icon_addr[icon_num],RASTER_MODE,icon_x[index]*offset,icon_y[index]*offset,MONO_ICON_W,MONO_ICON_H);
  1279.         else draw_icon(icon_addr[icon_num],RASTER_MODE,icon_x[index],icon_y[index],C_ICON_W,C_ICON_H);
  1280.     }
  1281.     show_sprites();
  1282.     Setscreen(log_scr,phys_scr,-1);
  1283.     Vsync();
  1284.     form_dollar(TRUE);
  1285.     graf_mouse(M_ON,0L);
  1286. }
  1287.  
  1288.  
  1289. /*********************************************************************
  1290. *    load_map_screen()
  1291. *
  1292. *    This routine loads in the DEGAS MAP screen and sets the color
  1293. *    palette for the game.
  1294. **********************************************************************/
  1295.  
  1296. load_map_screen()
  1297. {
  1298.     int palette[16], buf[20];
  1299.     int fh;
  1300.  
  1301.     if (offset == 2) fh = open("\USAMAPHI.PI3", O_BINARY);
  1302.     if (offset == 1) fh = open("\USAMAPLO.PI1", O_BINARY);
  1303.     read(fh,buf,2);
  1304.     read(fh,palette,32);
  1305.     Setpalette(palette);
  1306.     read(fh,usamap,32000);
  1307.     close(fh);
  1308. }
  1309.  
  1310.  
  1311. /*********************************************************************
  1312. *    scr_copy()
  1313. *
  1314. *    This routine copies memory between two screens.  We call the
  1315. *    raster() function to do the chores.
  1316. **********************************************************************/
  1317.  
  1318. scr_copy(scr1,scr2)
  1319. long scr1,scr2;
  1320. {
  1321.     raster(scr1,scr2,0,0,320 * offset,200 * offset);
  1322. }
  1323.  
  1324.  
  1325. /*********************************************************************
  1326. *    show_sprites()
  1327. *
  1328. *    This routine places the player tokens on the screen.  This routine
  1329. *    is only called for an entire screen redraw.
  1330. **********************************************************************/
  1331.  
  1332. show_sprites()
  1333. {
  1334.     int plr_num,sx,sy;
  1335.     
  1336.     graf_mouse(M_OFF,0L);
  1337.     for (plr_num = 0; plr_num < 4; plr_num++) {
  1338.         if (on_board[plr_num] == TRUE) {
  1339.             if (board_pos[plr_num] == NPROP) {
  1340.                 sx = 180 * offset + plr_num * 16;
  1341.                 sy = 170 * offset;
  1342.             }
  1343.             else {
  1344.                 sx = (icon_x[board_pos[plr_num]] + 4) * offset;
  1345.                 sy = (icon_y[board_pos[plr_num]] + 4) * offset;
  1346.             }
  1347.             switch (plr_num) {
  1348.                 case 0:
  1349.                     a_drawsprite(sx,sy,sprites[0],spr1);
  1350.                     break;
  1351.                 case 1:
  1352.                     a_drawsprite(sx,sy,sprites[1],spr2);
  1353.                     break;
  1354.                 case 2:
  1355.                     a_drawsprite(sx,sy,sprites[2],spr3);
  1356.                     break;
  1357.                 case 3:
  1358.                     a_drawsprite(sx,sy,sprites[3],spr4);
  1359.                     break;
  1360.             }
  1361.         }
  1362.     }
  1363.     graf_mouse(M_ON,0L);
  1364. }
  1365.  
  1366.  
  1367. /*********************************************************************
  1368. *    sprite_move()
  1369. *
  1370. *    This is responsible for moving a sprite around on the screen.  We
  1371. *    use the LINE-A sprite draw/undraw routines.
  1372. **********************************************************************/
  1373.  
  1374. sprite_move(spr_num,property)
  1375. int spr_num,property;
  1376. {
  1377.     int sx,sy;
  1378.  
  1379.     sx = (icon_x[property] + 4) * offset;
  1380.     sy = (icon_y[property] + 4) * offset;
  1381.     graf_mouse(M_OFF,0L);
  1382.     
  1383.     switch (spr_num) {
  1384.         case 0:
  1385.             a_undrawsprite(spr1);
  1386.             break;
  1387.         case 1:
  1388.             a_undrawsprite(spr2);
  1389.             break;
  1390.         case 2:
  1391.             a_undrawsprite(spr3);
  1392.             break;
  1393.         case 3:
  1394.             a_undrawsprite(spr4);
  1395.             break;
  1396.     }
  1397.     Dosound(crash);
  1398.     show_sprites();
  1399.     graf_mouse(M_ON,0L);
  1400. }
  1401.  
  1402.  
  1403. /*********************************************************************
  1404. *    roll_dice()
  1405. *
  1406. *    This is where we roll the dice.  When we enter here the dice
  1407. *    automatically begin to roll, the player presses the mouse button
  1408. *    to stop them.  The function returns an int that is the sum of
  1409. *    the two die.
  1410. **********************************************************************/
  1411.  
  1412. int roll_dice()
  1413. {
  1414.     int die1,die2,j,            /* function variables */
  1415.         button,mx,my,            /* mouse info */
  1416.         dx,dy,dw,dh,            /* dialog x,y,w,h */
  1417.         quit_flag = 0;            /* game quit flag */
  1418.     OBJECT *tree;
  1419.     long old_mousev,dummy;
  1420.  
  1421.     vex_butv(handle,mouse_rts,&old_mousev);
  1422.     do {
  1423.         die1 = rnd(6);
  1424.         die2 = rnd(6);
  1425.         
  1426.         graf_mouse(M_OFF,0L);
  1427.         if (offset == 2) {
  1428.             draw_icon(dice[die1],12,182,128,MONO_DIE_W,MONO_DIE_H);
  1429.             draw_icon(dice[die2],12,262,128,MONO_DIE_W,MONO_DIE_H);
  1430.         }
  1431.         else {
  1432.             draw_icon(dice[die1],RASTER_MODE,91,64,C_DIE_W,C_DIE_H);
  1433.             draw_icon(dice[die2],RASTER_MODE,131,64,C_DIE_W,C_DIE_H);
  1434.         }
  1435.         graf_mouse(M_ON,0L);
  1436.         wait_jiffy(8);
  1437.         vq_mouse(handle,&button,&mx,&my);
  1438.         if (button == LEFT) quit_flag = 1;
  1439.         if (button == RIGHT) {
  1440.             rsrc_gaddr(0,ENDGAME,&tree);
  1441.             draw_dialog(tree,&dx,&dy,&dw,&dh,TRUE);
  1442.             vex_butv(handle,old_mousev,&dummy);
  1443.             j = form_do(tree,0);
  1444.             if (j == ENDYES) quit_flag = -1;
  1445.             if (j == ENDNO ) quit_flag = 0;
  1446.             close_dialog(dx,dy,dw,dh,TRUE);
  1447.             vex_butv(handle,mouse_rts,&old_mousev);
  1448.         }
  1449.     } while (quit_flag == 0);
  1450.     vex_butv(handle,old_mousev,&dummy);
  1451.     return((die1 + die2 + 2) * quit_flag);
  1452. }
  1453.  
  1454.  
  1455. /*********************************************************************
  1456. *    form_dollar()
  1457. *
  1458. *    This routine displays how much money each player has left.
  1459. *    This display is in the lower left corner of the screen.  If the
  1460. *    flag is TRUE the "PLAYER UP" is not drawn.  (This is because in
  1461. *    low-res the transaction dialog overlaps the "BANK" on screen.
  1462. **********************************************************************/
  1463.  
  1464. form_dollar(flag)
  1465. int flag;
  1466. {
  1467.     char string[40],num[10];    /* character output string */
  1468.     int i,j,k,n;
  1469.     
  1470.     vst_font(handle,1);
  1471.     vst_alignment(handle,0,0,&i,&i);
  1472.     if (offset == 2) vst_height(handle,13,&i,&i,&i,&i);
  1473.     else vst_height(handle,4,&i,&i,&i,&i);
  1474.     vst_color(handle,1);
  1475.     vswr_mode(handle,1);
  1476.     vst_effects(handle,NORMAL);
  1477.  
  1478.     if (flag == TRUE) {
  1479.         j = 8 - strlen(player_names[player]);
  1480.         for (k = 0; k < 40; k++) string[k] = ' ';
  1481.         sprintf(&string[j],"%d UP: %s",player + 1,player_names[player]);
  1482.         v_gtext(handle, 8 * offset, 8 * offset + 155 * offset, string);
  1483.     }
  1484.  
  1485.     for (i = 0; i < num_players; i++) {
  1486.         j = 8 - strlen(player_names[i]);
  1487.         sprintf(num,"%dG",cash[i]);
  1488.         n = 4 - strlen(num);
  1489.         for (k = 0; k <10; k++) num[k] = ' ';
  1490.         sprintf(&num[n],"%dG",cash[i]);
  1491.         for (k = 0; k < 40; k++) string[k] = ' ';
  1492.         if (cash[i] > 0) sprintf(&string[j],"%s: %s",player_names[i],num);
  1493.         else sprintf(&string[j],"%s:BROKE",player_names[i]);
  1494.         v_gtext(handle, 8 * offset, 8 * offset * i + 171 * offset, string);
  1495.     }
  1496. }
  1497.  
  1498.  
  1499. /*********************************************************************
  1500. *    print_prop()
  1501. *
  1502. *    This prints out the name of the property that the players token
  1503. *    is currently on.  The name is printed on the long white box at the
  1504. *    bottom of the screen.  We first erase the old property name and
  1505. *    then print the new name.
  1506. **********************************************************************/
  1507.  
  1508. print_prop(pr)
  1509. int pr;
  1510. {
  1511.     graf_mouse(M_OFF,0L);
  1512.     v_gtext(handle,111 * offset, 195 * offset, spaces);
  1513.     v_gtext(handle,111 * offset, 195 * offset, prop_names[pr]);
  1514.     graf_mouse(M_ON,0L);
  1515. }
  1516.  
  1517.  
  1518. /*********************************************************************
  1519. *    wait_jiffy()
  1520. *
  1521. *    This procedure waits DELAY jiffies.  This is used to time certain
  1522. *    operations and to sync the graphics with the screen draws.
  1523. **********************************************************************/
  1524.  
  1525. wait_jiffy(delay)
  1526. int delay;
  1527. {
  1528.     while (delay--) Vsync();
  1529. }
  1530.  
  1531.  
  1532. /*********************************************************************
  1533. *    do_intro()
  1534. *
  1535. *    This is the INTRO routine.  All we do is copy the USAMAP to the
  1536. *    screen and display the INT_DIAL dialog.
  1537. **********************************************************************/
  1538.  
  1539. do_intro()
  1540. {
  1541.     int choice,dx,dy,dw,dh;
  1542.     OBJECT *tree;
  1543.     
  1544.     scr_copy(usamap,Logbase());
  1545.     if (offset == 1) rsrc_gaddr(0,INT_DIAL,&tree);
  1546.     else rsrc_gaddr(0,MONO_INT,&tree);
  1547.     draw_dialog(tree,&dx,&dy,&dw,&dh,TRUE);
  1548.     form_do(tree,0);
  1549.     close_dialog(dx,dy,dw,dh,TRUE);
  1550. }
  1551.  
  1552.  
  1553. /*********************************************************************
  1554. *    draw_dialog()
  1555. *
  1556. *    This function opens a dialog box on the screen AND saves the
  1557. *    underlying graphics so that a fast re-draw may be done.
  1558. *    The function needs the following parameters:
  1559. *    
  1560. *    tree    : the resource tree address
  1561. *    &dx        : the variable that will be the dialogs X coord
  1562. *    &dy        : the dialog Y coord
  1563. *    &dw        : the dialog Width
  1564. *    &dh        : the dialog Height
  1565. *    flag    : flag for whether a GROW_BOX is drawn
  1566. **********************************************************************/
  1567.  
  1568. draw_dialog(tree,x,y,w,h,flag)
  1569. OBJECT *tree;
  1570. int    *x,*y,*w,*h,flag;
  1571. {
  1572.     int x1,y1;
  1573.     
  1574.     x1 = *x + *w / 2;
  1575.     y1 = *y + *h / 2;
  1576.     form_center(tree,x,y,w,h);
  1577.     raster(Physbase(),backup,*x,*y,*w+1,*h+2);
  1578.     if (flag == TRUE) form_dial(FMD_GROW,x1,y1,10,10,*x,*y,*w,*h);
  1579.  
  1580.     form_dial(FMD_START,x1,y1,10,10,*x,*y,*w,*h);
  1581.     objc_draw(tree,ROOT,MAX_DEPTH,*x,*y,*w,*h);
  1582. }
  1583.  
  1584.  
  1585. /*********************************************************************
  1586. *    close_dialog()
  1587. *
  1588. *    This routine is responsible for closing the currently open dialog
  1589. *    on the screen.  If flag == TRUE a shrinking box is drawn.  The
  1590. *    routine restores the screen area under the dialog making the
  1591. *    redraw of the map much faster and easier.
  1592. **********************************************************************/
  1593.  
  1594. close_dialog(x,y,w,h,flag)
  1595. int x,y,w,h,flag;
  1596. {
  1597.     int x1,y1;
  1598.  
  1599.     x1 = x + w / 2;
  1600.     y1 = y + h / 2;
  1601.     
  1602.     form_dial(FMD_FINISH,x1,y1,10,10,x,y,w,h);
  1603.     raster(backup,Physbase(),x,y,w+1,h+2);
  1604.     if (flag) form_dial(FMD_SHRINK,x1,y1,10,10,x,y,w,h);
  1605. }
  1606.  
  1607.  
  1608. /*********************************************************************
  1609. *    raster()
  1610. *
  1611. *    This function will copy a screen raster of ANY size from source
  1612. *    to destn.  The raster is copied to the same coordinates on both
  1613. *    screens.
  1614. *********************************************************************/
  1615.  
  1616. raster(source,destn,x,y,w,h)
  1617. long source,destn;
  1618. int x,y,w,h;
  1619. {
  1620.     MFDB src,dst;
  1621.     int pxy[8],w16;
  1622.     char nums[50];
  1623.     
  1624.     h--;
  1625.     w16 = w;
  1626.     if (w != ((w / 16) * 16)) w16 = ((w / 16) + 1) * 16;
  1627.  
  1628.     graf_mouse(M_OFF,0L);
  1629.     if (source == Physbase()) src.fd_addr = 0;
  1630.     else {
  1631.         src.fd_addr = source;
  1632.         src.fd_w    = w16;
  1633.         src.fd_h    = h;
  1634.         src.fd_wdwidth = w16 / 16;
  1635.         src.fd_stand= 0;
  1636.         src.fd_nplanes = nplanes;
  1637.     }
  1638.  
  1639.     if (destn == Physbase()) dst.fd_addr = 0;
  1640.     else {
  1641.         dst.fd_addr = destn;
  1642.         dst.fd_w    = w16;
  1643.         dst.fd_h    = h;
  1644.         dst.fd_wdwidth = w16 / 16;
  1645.         dst.fd_stand= 0;
  1646.         dst.fd_nplanes = nplanes;
  1647.     }
  1648.  
  1649.     pxy[0] = x;
  1650.     pxy[1] = y;
  1651.     pxy[2] = x + w;
  1652.     pxy[3] = y + h;
  1653.     pxy[4] = x;
  1654.     pxy[5] = y;
  1655.     pxy[6] = x + w;
  1656.     pxy[7] = y + h;
  1657.     vro_cpyfm(handle,RASTER_MODE,pxy,&src,&dst);
  1658.     graf_mouse(M_ON,0L);
  1659. }
  1660.  
  1661.  
  1662. /*********************************************************************
  1663. *    mouse_rts()
  1664. *
  1665. *    This empty routine assembles to an RTS instruction.  We point the
  1666. *    VDI button handler here so that we do not get mouse button bleed 
  1667. *    throughs from the AES and VDI.
  1668. **********************************************************************/
  1669. mouse_rts()
  1670. {
  1671. }
  1672.